package com.xzy.learn.spring.bean.creation;

import com.xzy.learn.spring.service.StudentService;
import com.xzy.learn.spring.service.impl.StudentServiceImpl1;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;

/**
 * 实例化 Bean 的特殊方式
 *
 * @author xzy.xiao
 * @date 2022/6/1  10:52
 */
public class SpecialBeanCreationDemo {
    public static void main(String[] args) {
        specialBeanCreation();
    }

    /**
     * 特殊的创建 Bean 的方式
     */
    public static void specialBeanCreation() {
        createBeanByServiceLoaderFactoryBean();
        createBeanByAutowireCapableBeanFactory();
    }

    public static void serviceLoaderUseDemo() {
        System.out.println("借助 ServiceLoader 加载 StudentService 接口的实例：");
        ServiceLoader<StudentService> serviceLoader = ServiceLoader.load(StudentService.class, Thread.currentThread().getContextClassLoader());
        Iterator<StudentService> serviceIterator = serviceLoader.iterator();
        serviceIterator.forEachRemaining(System.out::println);
    }

    /**
     * ServiceLoaderFactoryBean
     */
    public static void createBeanByServiceLoaderFactoryBean() {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/special-bean-creation.xml");
        Map<String, ServiceLoader> beansOfType = classPathXmlApplicationContext.getBeansOfType(ServiceLoader.class);
        beansOfType.forEach((id, serviceLoader) -> {
            System.out.println(id + " -> " + serviceLoader);
            serviceLoader.forEach(System.out::println);
        });
    }

    /**
     * AutowireCapableBeanFactory
     */
    public static void createBeanByAutowireCapableBeanFactory() {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/special-bean-creation.xml");
        AutowireCapableBeanFactory autowireCapableBeanFactory = classPathXmlApplicationContext.getAutowireCapableBeanFactory();

        StudentService bean = autowireCapableBeanFactory.createBean(StudentServiceImpl1.class);
        System.out.println(bean);
    }
}
